package spring;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.MethodInterceptor;
import spring.annotation.toProxy;
import zhaoxiaohan.service.MyAspect;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;

/**
 * @author zxh
 */
public class AbstractAutoProxyCreator implements Ordered,BeanPostProcessor {

    HashMap<String,Object> earlyProxyReferences = new HashMap<>(16);

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        Class<?> aClass = bean.getClass();
        if(aClass.isAnnotationPresent(toProxy.class)){
            if (bean != null) {
                // 解决循环引用，如果已经创建过了对象，如果创建过了就直接返回了
                // 动态代理，运用了字节码技术，在运行的过程中，动态的加入额外功能 ===> 运行效率低于静态代理，但是灵活，改起来更方便
                // 如果我们想要追求效率，我们就不会去使用框架了
                if (this.earlyProxyReferences.remove(beanName) != bean) {
                    return wrapIfNecessary(bean, beanName);
                }
            }
        }
        return bean;

    }

    // 使用CGLib实现代理
    private Object wrapIfNecessary(Object bean, String beanName) {

        Enhancer enhancer = new Enhancer();
        enhancer.setClassLoader(this.getClass().getClassLoader());
        enhancer.setSuperclass(bean.getClass());
        MethodInterceptor interceptor = (o, method, objects, methodProxy) -> {
            Object invoke = null;
            try {
                System.out.println("执行代理方法");
                invoke = method.invoke(bean, objects);
            } catch (Exception e) {
                System.err.println("方法执行出错：" + e.getMessage());
            }
            return invoke;
        };
        enhancer.setCallback(interceptor);
        return enhancer.create();

    }

}
